
//
//  RunLoopContext.m
//  ETAClient-iPhoneOS
//
//  Created by Daniel Reed on 9/7/10.
//  Copyright 2010 N/a. All rights reserved.
//

#import "RunLoopContext.h"


@implementation RunLoopContext
#pragma mark -
#pragma mark Synthesize directives
@synthesize target;
@synthesize selector;
@synthesize context;
@synthesize source;
@synthesize runLoop;

#pragma mark -
#pragma mark Custom initializers
-(id) initWithTarget: (id) aTarget selector: (SEL) aSelector
{
    if (self = [super init])
    {
        target = aTarget;
        selector = aSelector;
    }
    
    return self;
}


#pragma mark -
#pragma mark Public methods
-(BOOL) isValid
{
    return CFRunLoopSourceIsValid(source);
}

-(void) invalidate
{
    CFRunLoopSourceInvalidate(source);
}

-(void) signal
{
    CFRunLoopSourceSignal(source);
    CFRunLoopWakeUp(runLoop);
}

-(void) invoke
{
    // Perform the target selector.
    [target performSelector: selector];
}

-(void) scheduleInCFRunLoop: (CFRunLoopRef) aRunLoop forMode: (CFStringRef) aMode
{
    // Setup the context.
    context.version = 0;
    context.info = self;
    context.retain = NULL;
    context.release = NULL;
    context.copyDescription = CFCopyDescription;
    context.equal = CFEqual;
    context.hash = CFHash;
    context.schedule = RunLoopSourceScheduleRoutine;
    context.cancel = RunLoopSourceCancelRoutine;
    context.perform = RunLoopSourcePerformRoutine;
    
    // Store the configured runloop and mode.
    runLoop = aRunLoop;
    mode = aMode;
    
    // Create the CFRunLoopSourceRef.
    source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
    
    // Add the new CFRunLoopSourceRef to the indicated runloop.
    CFRunLoopAddSource(runLoop, source, mode);
}

#pragma mark -
#pragma mark Overriden inherited methods
-(void) dealloc
{
    // Invalidate.
    [self invalidate];
    
    // Set retained objects/values to nil.
    target = nil;
    selector = nil;
    
    // Invoke the inherited dealloc method.
    [super dealloc];
}
@end

#pragma mark -
#pragma mark CFRunLoopSourceContext callbacks
void RunLoopSourceScheduleRoutine(void* info, CFRunLoopRef rl, CFStringRef mode)
{
    // Cast the info pointer to a RunLoopContext instance.
    RunLoopContext* ctx = (RunLoopContext*) info;
}

void RunLoopSourcePerformRoutine (void* info)
{
    // Cast the info pointer to a RunLoopContext instance.
    RunLoopContext* ctx = (RunLoopContext*) info;
    
    if (ctx)
    {
        [ctx invoke];
    }
}

void RunLoopSourceCancelRoutine (void* info, CFRunLoopRef rl, CFStringRef mode)
{
    
}